package com.lcx.core;

import com.lcx.constact.PageVeriable;
import com.lcx.constact.Path;
import com.lcx.util.CopyFileUtil;

import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * 拷贝内部资源到外部
 */
public class StartingTodo {

    /**
     * 指定路径拷贝资源，可以是任意路径
     * @param ownPath
     * @throws Exception
     */
    public static void copyResource(String ownPath) throws Exception{
        if(System.getProperty("os.name").toLowerCase().contains("windows")){
            ownPath=ownPath.substring(1);
        }
        File ownFile = new File(ownPath);
        if(ownFile.isFile()){
            ZipFile zipFile = new ZipFile(ownPath, Charset.forName("UTF-8"));
            Enumeration<? extends ZipEntry> zes = zipFile.entries();
            int index;
            String dir="";
            String fileName=null;
            String content1 = Path.contentPath;
            String content2 = Path.contentPath+"/";
            while (zes.hasMoreElements()) {
                ZipEntry ze = zes.nextElement();
                if(ze.getName().equals(content1) || ze.getName().startsWith(content2)){
                    if (!ze.isDirectory()) {
                        if((index=ze.getName().lastIndexOf("/"))>-1){
                            dir = Path.targetPath+"/"+ze.getName().substring(0,index);
                            new File(dir).mkdirs();
                            fileName=Path.targetPath+"/"+ze.getName();
                        }
                        InputStream is = null;
                        FileOutputStream fos = null;
                        try {
                            is = zipFile.getInputStream(ze);
                            fos = new FileOutputStream(new File(fileName));
                            byte b[] = new byte[1024];
                            int read;
                            while((read=is.read(b))>-1){
                                fos.write(b,0,read);
                            }
                            fos.flush();
                        } catch (Exception e) {
                        }finally {
                            try{
                                fos.close();
                            }catch (Exception e){}
                            try{
                                is.close();
                            }catch (Exception e){}
                        }
                    }
                }
            }
            zipFile.close();
        }else{
            CopyFileUtil.copyAllFile(new File(ownPath+"/"+Path.contentPath),new File(Path.targetPath));
        }
    }

    /**
     * 当你的应用与本资源在相同src下则使用该方法拷贝资源
     * @throws Exception
     */
    public static void copyResource() throws Exception{
        String ownPath = URLDecoder.decode(StartingTodo.class.getProtectionDomain().getCodeSource().getLocation().getPath(),"UTF-8");
        copyResource(ownPath);
    }

    /**
     * 如果资源文件在某个类所属的src下可使用该方法copy
     * @param clazz
     * @throws Exception
     */
    public static void copyResource(Class<?> clazz) throws Exception{
        String ownPath = URLDecoder.decode(clazz.getProtectionDomain().getCodeSource().getLocation().getPath(),"UTF-8");
        copyResource(ownPath);
    }

    /**
     * 通过Path.settingPaths属性对指定资源文件中的通配符替换。
     * 使用PageVeriable下的变量对指定内容替换。
     * @throws Exception
     */
    public static void setPath() throws Exception{
        String ps[] = Path.settingPaths.split(",");
        for(String str:ps){
            setPath(new File(str));
        }
    }

    private static void setPath(File handle) throws Exception{
        if(handle.isDirectory()){
            File fs[] = handle.listFiles();
            if(fs!=null){
                for(File f:fs){
                    setPath(f);
                }
            }
            return;
        }
        FileInputStream fis = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        StringBuilder sb = null;
        try {
            fis = new FileInputStream(handle);
            isr = new InputStreamReader(fis,"UTF-8");
            br = new BufferedReader(isr);
            sb = new StringBuilder();
            String read;
            while((read=br.readLine())!=null){
                sb.append(replace(read, PageVeriable.htmlVeriableParam)).append("\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return;
        } finally {
            try {
                br.close();
            } catch (Exception e) {
            }
            try {
                isr.close();
            } catch (Exception e) {
            }
            try {
                fis.close();
            } catch (Exception e) {
            }
        }

        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        try {
            fos = new FileOutputStream(handle);
            osw = new OutputStreamWriter(fos,"UTF-8");
            osw.write(sb.toString());
            osw.flush();
            fos.flush();
        }catch (Exception e){

        }finally {
            try{
                osw.close();
            }catch (Exception e){
            }
            try{
                fos.close();
            }catch (Exception e){
            }
        }
    }

    private static String replace(String str,Map<String,String> param){
        StringBuilder sb = new StringBuilder();
        Pattern p = Pattern.compile("\\$\\{[a-zA-Z0-9]+?\\}");
        Matcher m;
        int start=0,end=0;
        int index=0;
        boolean has;
        has=false;
        m = p.matcher(str);
        String _name;
        while(m.find()){
            has=true;
            start = m.start();
            end=m.end();
            _name=str.substring(start+2,end-1);
            sb.append(str.substring(index,start));
            sb.append(param.getOrDefault(_name,"${"+_name+"}"));
            index=end;
        }
        sb.append(str.substring(end));
        return sb.toString();
    }

}
